package kr.co.bettersoft.usedmarketandroid.activity;

import java.util.List;

import kr.co.bettersoft.usedmarketandroid.common.CommonConstant;
import kr.co.bettersoft.usedmarketandroid.common.UsedMarketRest;
import kr.co.bettersoft.usedmarketandroid.domain.UsedMarketMember;

import static kr.co.bettersoft.usedmarketandroid.common.CommonConstant.GCM_ID;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

import android.os.Vibrator;

import android.support.v4.app.NotificationCompat.Builder;

/**
 * GCMIntentService
 * 서버로부터 푸시 알림을 받기 위한 GCM 서비스 이다.
 * 
 * 어플 실행시 구글에 GCM 을 등록하고, GCM 아이디가 바꼈을 경우 서버에 업데이트 한다.
 * 서버로부터 푸시 알림을 받았을 경우 사용자에게 노티를 준다. 
 *
 */
public class GCMIntentService extends GCMBaseIntentService {
//////////////////////////////////////////////////////////////////////////////////////////////////////
// 변수	
	
	private final String TAG = "GCMIntentService";
	public String phoneNum = "";
	public boolean pushOn = true;
	
	UsedMarketChatRoomActivity usedMarketChatRoomActivity = (UsedMarketChatRoomActivity)UsedMarketChatRoomActivity.usedMarketChatRoomActivity;
	
	// 앱 중복 실행 방지
	public int count = 0;
	
	// 진동
	Vibrator Vi;	// 진동이 울리도록 하기 위함.
	int vibrateCnt = 3;

	// 서버 통신 관련
	Boolean dontTwice = true;
	
	// GCM
	String regIdGCM = "";
	Context localContext;
	String regResult="";

	// 설정 파일 저장소   -- 설정에 GCM ID 를 저장하여 GCM ID 가 변경된 경우에만 서버로 업데이트 한다.
	SharedPreferences sharedPrefCustom;
	String savedGCMId = "";

	
	String RunMode = "";
	// 채팅방정보
//	String message = "";
//	String receivedChatRoomId = "";
//	String receivedChatRoomOwner = "";
	String usedMarketChatIdUsedMarketChat = "";
	String usedMarketChatIdUsedMarketProduct = "";
	String usedMarketChatOwner = "";
	
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public GCMIntentService() {
		super(GCM_ID);
	}

	/**
	 * onRegistered
	 *  gcm 등록되면 비동기로 서버에 업데이트한다
	 *
	 * @param context
	 * @param registrationId
	 * @return
	 */
	@Override
	public void onRegistered(Context context, String registrationId) {
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
		
//		// prefs
//		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
//				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
//		savedGCMId = sharedPrefCustom.getString("savedGCMId", "");	
//		phoneNum = sharedPrefCustom.getString("phoneNum", "");
//		pushOn = sharedPrefCustom.getBoolean("pushOn", true);
		selectPreferenceData();
		
		if(dontTwice){			// 한번 하고 막는다.
			regIdGCM = registrationId;
			
			// gcm 푸시 테스트 위해. 잠시 주석 처리. 항시 서버에 올리도록.
//			if(!(savedGCMId.equals(regIdGCM))){	// pref 에 저장된것(=서버에 저장된것)과 등록한 GCM 아이디가 다를때에만 업데이트 하도록 한다.		// *** 
				new backgroundThreadUpdateMyGCMtoServer().execute();	// 비동기로 전환 - 서버에 GCM 아이디 저장	 *** 
				//            displayMessage(context, getString(R.string.gcm_registered));			// 브로드 케스트로 보내줌.. 리시버가 잡음. (노티는 없음)
				localContext = context;
				dontTwice = false;
//			}else{
//				Log.d(TAG,"saved GCM Id is not changed.");
//				// *** 업뎃 하지 않음.
//			}
		}
	}

	/**
	 * GCM ID 를 pref 설정에 저장한다.
	 */
	public void saveGCMIdToPref(){
		SharedPreferences.Editor updatesavedGCMId =   sharedPrefCustom.edit();
		updatesavedGCMId.putString("savedGCMId", regIdGCM);		// GCM ID저장
		updatesavedGCMId.commit();
	}
	
	@Override
	protected void onUnregistered(Context context, String registrationId) {
		Log.i(TAG, "Device unregistered");
	}

	/**
	 * onMessage
	 *  서버에서 푸시가 오면 사용자에게 노티를 준다
	 *
	 * @param context
	 * @param intent
	 * @return
	 */
	@Override		// GCM 서비스 에서 온 메시지 받은거.
	protected void onMessage(Context context, Intent intent) {
		Log.i(TAG, "Received message");
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

		// prefs  푸시 알림 설정 따라 알림
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		boolean pushOn = sharedPrefCustom.getBoolean("pushOn", true);
		if(pushOn){
			// 받은 전체
			String tmpStr = intent.getStringExtra("MESSAGE");
			
			// 채팅 메시지일때
			if(tmpStr.contains("NEW_MESSAGE")){
				RunMode = "NEW_MESSAGE";
				// 받은 데이터 분리시키기
//				String usedMarketChatIdUsedMarketChat = "";
//				String usedMarketChatIdUsedMarketProduct = "";
//				String usedMarketChatOwner = "";
				tmpStr = tmpStr.substring(11);
				String[] messages = tmpStr.split(":");
				if(messages.length>0){
					usedMarketChatIdUsedMarketChat = messages[0];
				}
				if(messages.length>1){
					usedMarketChatIdUsedMarketProduct = messages[1];
				}
				if(messages.length>2){
					usedMarketChatOwner = messages[2];
				}

				Log.d(TAG,"usedMarketChatIdUsedMarketChat::"+usedMarketChatIdUsedMarketChat);
				Log.d(TAG,"usedMarketChatIdUsedMarketProduct::"+usedMarketChatIdUsedMarketProduct);
				Log.d(TAG,"usedMarketChatOwner::"+usedMarketChatOwner);
				
				Log.i(TAG, "Received message of onMessage(): NEW_MESSAGE ::"+tmpStr);		

				// notifies user
				generateNotificationForNewMessage(context, usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner);	// 추가 작업. 
				
			}else{	// 채팅 메시지가 아닐때 - 무조건 노티.
				RunMode = tmpStr;
				Log.i(TAG, "Received message of onMessage():"+tmpStr);	
				generateNotification(context, tmpStr);	
			}
//			// notifies user
//			generateNotification(context, message);	// 사용자에게 노티를 준다
		}
	}

	@Override
	protected void onDeletedMessages(Context context, int total) {
		Log.i(TAG, "Received deleted messages notification");
	}

	@Override
	public void onError(Context context, String errorId) {
		Log.i(TAG, "Received error: " + errorId);
	}

	@Override
	protected boolean onRecoverableError(Context context, String errorId) {
		// log message
		Log.i(TAG, "Received recoverable error: " + errorId);
		return super.onRecoverableError(context, errorId);
	}

	/**
	 * generateNotification
	 * Issues a notification to inform the user that server has sent a message.
	 *   채팅 이외의 경우.
	 * @param context
	 * @param message
	 * @return
	 */
	private  void generateNotification(Context context, String message) {
		
		// 값유지가 안되서 매번 호출해준다.
		selectPreferenceData();
		
		if(pushOn){		// 알람을 받는 경우에만 진행.
			
			vibrateOneTimes();
			Log.d(TAG,"message::"+message);
			
			// 보여줄 메시지 결정
			/*
			 * 	NEW_INTEREST	새로운 관심물품이 등록되었습니다.
				NEW_PRODUCT_REPLY	새로운 물품 댓글이 등록되었습니다.
				NEW_COMMUNITY_REPLY	새로운 커뮤니티 댓글이 등록되었습니다.
				NEW_CHAT	새로운 채팅요청이 있습니다.
				NEW_MESSAGE	새로운 메시지가 등록되었습니다.
			 */
			String contents = "";
			if(message.equals("NEW_INTEREST")){		
				contents =  "새로운 관심물품이 등록되었습니다.";			
			}else if(message.equals("NEW_PRODUCT_REPLY")){
				contents =  "새로운 물품 댓글이 등록되었습니다.";		
			}else if(message.equals("NEW_COMMUNITY_REPLY")){
				contents =  "새로운 커뮤니티 댓글이 등록되었습니다.";		
			}else if(message.equals("NEW_CHAT")){
				contents =  "새로운 채팅요청이 있습니다.";		
			}else if(message.equals("NEW_MESSAGE")){
				contents =  "새로운 메시지가 등록되었습니다.";		
			}else{
				contents =  message;
			}
			///////////////////////
			Intent notificationIntent = new Intent(context, UsedMarketLauncherActivity.class);	// *** // 터치시 실행될 액티비티인가봉가

			// 공통부
			PendingIntent contentIntent = PendingIntent.getActivity(context,
					0, notificationIntent,
					PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
					.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)		// 우측 하단 작은 이미지.. -- 주석하니까 안나옴
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))		// 왼쪽 왕큰 이미지
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)		// 기본. 터치시 액티비티 실행하고 종료됨.
//			.setAutoCancel(false)		// 건드리는거로 종료되지 않음. 지우기 로는 지워짐.
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(contents);	// *** 
			Notification n = builder.build();
			nm.notify(0, n);
		}
	}
	/**
	 * generateNotification
	 * Issues a notification to inform the user that server has sent a message.
	 *  채팅 메시지의 경우.
	 * @param context
	 * @param message
	 * @return
	 */
	private  void generateNotificationForNewMessage(Context context, String usedMarketChatIdUsedMarketChat, String usedMarketChatIdUsedMarketProduct, String usedMarketChatOwner) {
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);

		selectPreferenceData();
		
		Boolean appRunningYn = sharedPrefCustom.getBoolean("appRunningYn", false);
		Boolean chatRoomUsingYn = sharedPrefCustom.getBoolean("chatRoomUsingYn", false);
		String currentUsedMarketChatIdUsedMarketChat = sharedPrefCustom.getString("currentUsedMarketChatIdUsedMarketChat", "");
		String currentUsedMarketChatIdUsedMarketProduct = sharedPrefCustom.getString("currentUsedMarketChatIdUsedMarketProduct", "");
		String currentUsedMarketChatOwner = sharedPrefCustom.getString("currentUsedMarketChatOwner", "");
		
		// 실행중인지 확인.
		isRunningProcess(this);
		if(appRunningYn==false){
			//실행중이 아님 -> 더미로 데이터 전달.   
			Log.d(TAG, "not running");
			passDataToDummyActivity(context, usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner);
		}else if(count<2 && appRunningYn){	// 실행중
			Log.d(TAG, "running");

			// 채팅방에 있는지 확인
			if(chatRoomUsingYn){	// 현재 채팅방에 있음
				Log.d(TAG, "in chat room");

				// 동일한 채팅방인지 확인. 방번호와 제품번, 방장 전번 등 이용.
				if(usedMarketChatIdUsedMarketChat.equals(currentUsedMarketChatIdUsedMarketChat) 
						&& usedMarketChatIdUsedMarketProduct.equals(currentUsedMarketChatIdUsedMarketProduct)
						&& usedMarketChatOwner.equals(currentUsedMarketChatOwner)){	// 동일한 채팅방
					Log.d(TAG, "same chat room");

					//						// 동일 방에 있을때 업데이트 호출.
					usedMarketChatRoomActivity.callRefresh();

				}else{	// 다른 채팅방에 있을때 -> 노티 처리 액티비티로 데이터 전달
					Log.d(TAG, "other chat room");
					passDataToDummyActivity(context, usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner);	// *** 
				}                
			}else{		// 채팅방에 없을때 -> 노티 처리 액티비티로 데이터 전달 
				Log.d(TAG, "not chat room");
				passDataToDummyActivity(context, usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner);
			}
		}else{	// 실행중이 아님 -> 노티 처리 액티비티로 데이터 전달.   
			Log.d(TAG, "not running");
			passDataToDummyActivity(context, usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner);
		}	
	}
	
	
	/**
	 * 더미 액티비티로 데이터를 전달하는 노티를 생성한다.
	 *   usedMarketChatIdUsedMarketChat, usedMarketChatIdUsedMarketProduct, usedMarketChatOwner
	 */
	public void passDataToDummyActivity(Context context, String usedMarketChatIdUsedMarketChat, String usedMarketChatIdUsedMarketProduct, String usedMarketChatOwner){
		//			int icon = R.drawable.ic_launcher;		
		
		// 값유지가 안되서 매번 호출해준다.
		selectPreferenceData();
		
		if(pushOn){		// 알람을 받는 경우에만 진행.
			
			vibrateOneTimes();
			Log.d(TAG,"usedMarketChatIdUsedMarketChat::"+usedMarketChatIdUsedMarketChat);
			
			String contents = "";
			contents =  "새로운 메시지가 등록되었습니다.";		
	
			///////////////////////
			Intent notificationIntent = new Intent(context, NotiTouchActionControlActivity.class);	// *** 
			// 데이터 전달	 *** 
			sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
					Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
			phoneNum = sharedPrefCustom.getString("phoneNum", "");
			Log.d(TAG,"notificationIntent phoneNum:"+phoneNum);
			notificationIntent.putExtra("RunMode", RunMode);		
			notificationIntent.putExtra("receivedUserId", phoneNum);						 
	//		notificationIntent.putExtra("chatRoomId", receivedChatRoomId);				 		
	//		notificationIntent.putExtra("chatRoomOwner", receivedChatRoomOwner);	
			notificationIntent.putExtra("usedMarketChatIdUsedMarketChat", usedMarketChatIdUsedMarketChat);	
			notificationIntent.putExtra("usedMarketChatIdUsedMarketProduct", usedMarketChatIdUsedMarketProduct);	
			notificationIntent.putExtra("usedMarketChatOwner", usedMarketChatOwner);	
	
			// 공통부
			PendingIntent contentIntent = PendingIntent.getActivity(context,
					0, notificationIntent,
					PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)		// 우측 하단 작은 이미지.. -- 주석하니까 안나옴
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))		// 왼쪽 왕큰 이미지
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(contents);	// *** 
			Notification n = builder.build();
			nm.notify(0, n);
		}
	}
	
	
	
///////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * backgroundThreadUpdateMyGCMtoServer
	 * 비동기  .   GCM 아이디 업뎃 호출  -- 서버에 gcm 아이디 업뎃
	 * @author blue
	 *
	 */
	public class backgroundThreadUpdateMyGCMtoServer extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadUpdateMyGCMtoServer");
			if(phoneNum==null || phoneNum.length()<1){
				// qr 없으면 업데이트 하지 않음
			}else{			// qr 있을때에만 업데이트 
				
				// 파라미터 세팅
				UsedMarketMember usedMarketMember = new UsedMarketMember();
				usedMarketMember.setPhoneNumber(phoneNum);	
				usedMarketMember.setPushId(regIdGCM);
				
				UsedMarketRest usedMarketRest = new UsedMarketRest();
				String callResult = usedMarketRest.RestUpdateMyGCMtoServer(usedMarketMember);
				
				// 결과 처리 
				if(callResult.equals("SUCCESS")){				//  성공
	    			Log.i(TAG, "S to update GCM ID to server");
	    			// 서버에 성공적으로 저장되면 설정에도 저장한다.
	    			saveGCMIdToPref();
	    		}else{														//  실패
	    			Log.i(TAG, "F to update GCM ID to server");
	    		}
			}
			return null; 
		}
	}
	

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public Context returnThis(){
		return this;
	}
	
	public void selectPreferenceData(){
		// prefs
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		savedGCMId = sharedPrefCustom.getString("savedGCMId", "");	
		phoneNum = sharedPrefCustom.getString("phoneNum", "");
		pushOn = sharedPrefCustom.getBoolean("pushOn", true);
	}
	
	
	// 진동 1
	public void vibrateOneTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
								Vi.vibrate(1000);
								Thread.sleep(2000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
	// 진동 3
	public void vibrateNTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
							for(int i=0; i<vibrateCnt; i++){
								Vi.vibrate(1000);
								Thread.sleep(2000);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
	
	/**
	 * isRunningProcess
	 *  중복 실행 방지를 위해 카운팅 체크를 한다.
	 *
	 * @param context
	 * @return isRunning
	 */
	public boolean isRunningProcess(Context context) {
		String PACKAGE_NAME;
		PACKAGE_NAME = getApplicationContext().getPackageName();
		count = 0;
		boolean isRunning = false;
		ActivityManager actMng = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);   
		List<RunningAppProcessInfo> list = actMng.getRunningAppProcesses();
		for(RunningAppProcessInfo rap : list) {
			if(rap.processName.equals(PACKAGE_NAME)) {			// PACKAGE_NAME		// packageName
				isRunning = true;
				count= count+1;		// 실행중인  수 (중복 실행 방지 용)
				Log.d("Log","count:"+count);
				break;
			}
		}
		return isRunning;
	}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
}
